package com.smartcar.auth.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.smartcar.auth.feign.AdminFeign;
import com.smartcar.auth.feign.AdminFeignServiceTemLate;
import com.smartcar.auth.service.AuthService;
import com.smartcar.common.constants.JwtConstants;
import com.smartcar.common.constants.TokenConstants;
import com.smartcar.common.domain.User;
import com.smartcar.common.domain.request.FindUserVo;
import com.smartcar.common.domain.request.LoginRequest;
import com.smartcar.common.domain.request.UpdateLoginVo;
import com.smartcar.common.domain.response.TokenResponse;
import com.smartcar.common.result.Result;
import com.smartcar.common.utils.JwtUtils;
import com.smartcar.common.utils.SnowFlakeUtil;
import com.smartcar.common.utils.StringUtils;
import com.smartcar.common.utils.TelSmsUtils;
import com.smartcar.common.utils.md5.Md5;
import com.smartcar.common.utils.verify.Verify;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.net.InetAddress;
import java.net.UnknownHostException;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
@Log4j2
public class AuthServiceImpl implements AuthService {

    @Autowired
    private AdminFeignServiceTemLate adminFeignServiceTemLate;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private HttpServletRequest request1;


    @Override
    @Transactional
    public Result<TokenResponse> login(LoginRequest loginRequest) {
        // 验证前台参数
        if (StringUtils.isEmpty(loginRequest.getUsername())) {
            return Result.error("账号不能为空，眼角膜用不上可以送给需要的人");
        }
        if (StringUtils.isEmpty(loginRequest.getPassword())) {
            return Result.error("密码不能为空，什么脑子");
        }
        User user = new User();
        // 判断用户是否存在 ， 账号密码
        try {
            user = adminFeignServiceTemLate.findUserByUserName(new FindUserVo(loginRequest.getUsername(), loginRequest.getRoleId()));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        // 验证用户是否存在
        if (null == user) {
            return Result.error("账号不存在，亲，注册个账号？");
        }
        // 验证账号信息是否正确
        if (!user.getUsername().equals(loginRequest.getUsername()) || !Md5.verifyMD5(loginRequest.getPassword(), user.getPassword())) {
            return Result.error("账户或密码错误，加油，差一点你就进来了");
        }
        // 生成token令牌
        HashMap<String, Object> cliams = new HashMap<>();
        String userKey = UUID.randomUUID().toString().replaceAll("-", "");
        cliams.put(JwtConstants.DETAILS_USER_ID, user.getId());
        cliams.put(JwtConstants.USER_KEY, userKey);
        String token = JwtUtils.createToken(cliams);
        // 存入redis缓存 --> 过期时间30分钟
        redisTemplate.opsForValue().set(TokenConstants.LOGIN_TOKEN_KEY + userKey, JSON.toJSONString(user), 30, TimeUnit.MINUTES);
        // 设置返回结果
        TokenResponse tokenResponse = new TokenResponse();
        tokenResponse.setToken(token);
        tokenResponse.setExpireTime("30MIN");
        //修改登录后参数
        UpdateLoginVo updateLoginVo = new UpdateLoginVo();
        updateLoginVo.setUsername(user.getUsername());
        updateLoginVo.setPassword(user.getPassword());
        try {
            adminFeignServiceTemLate.updateLoginAdmin(updateLoginVo);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        //返回结果
        return Result.success(tokenResponse);
    }

    @Override
    @Transactional
    public User userInfo() {
        // 拿到token令牌
        String token = request1.getHeader(TokenConstants.TOKEN);
        // 取出userKey
        String userKey = JwtUtils.getUserKey(token);
        // 从redis中取出用户信息 --> json字符串
        String jsonStr = redisTemplate.opsForValue().get(TokenConstants.LOGIN_TOKEN_KEY + userKey);
        // 返回解析的用户信息
        User user = JSONObject.parseObject(jsonStr, User.class);
        return user;
    }

    @Override
    @Transactional
    public Result logout() {
        // 拿到token令牌
        String token = request1.getHeader(TokenConstants.TOKEN);
        // 取出userKey
        String userKey = null;
        try {
            userKey = JwtUtils.getUserKey(token);
        } catch (Exception e) {
            // throw new RuntimeException(e);
            return Result.success("登出成功");
        }
        // 删除redis中的用户信息
        redisTemplate.delete(TokenConstants.LOGIN_TOKEN_KEY + userKey);
        return Result.success("登出成功");
    }

    @Override
    @Transactional//注册
    public Result registered(User user) {
        // 账号，昵称，角色，密码，状态，删除标识不能 为 null
        if (StringUtils.isEmpty(user.getUsername())) {
            return Result.error("账号不能为空");
        }
        try {
            if (null != adminFeignServiceTemLate.verifyUniqueUserName(user.getUsername())) {
                return Result.error("账号已存在，赶紧换了，麻溜的");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        if (StringUtils.isEmpty(user.getNickName())) {
            return Result.error("昵称不能为空");
        }
        if (StringUtils.isEmpty(user.getPassword())) {
            return Result.error("密码不能为空");
        }
        // 验证数据格式
        if (!Verify.verifyUserName(user.getUsername())) {
            return Result.error("账号格式不正确");
        }
        if (!Verify.verifypassword(user.getPassword())) {
            return Result.error("密码格式不正确");
        }
        // 如果手机号不为空则验证
        if (null == user.getPhone()) {

        } else {
            if (!Verify.verifyPhoneNumber(user.getPhone())) {
                return Result.error("手机号格式不正确");
            }
        }
        //获取验证码
        String code = redisTemplate.opsForValue().get(user.getPhone());
        if (StringUtils.isEmpty(code)) {
            return Result.error("请重新发送验证码");
        }
        if (!code.equals(user.getCode())) {
            return Result.error("验证码错误");
        }
        //获取用户编号 --> 雪花算法 + 时间戳
        user.setNumber(SnowFlakeUtil.getDefaultSnowFlakeId() + "_" + System.currentTimeMillis());
        //获取本机ip地址
        try {
            user.setCreateIp(InetAddress.getLocalHost().getHostAddress());
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException();
        }
        // 赋予用户角色 --> 用户：1代表普通用户
        // user.setRoleId(1);
        // 密码加密 --> md5
        user.setPassword(Md5.encryptMD5(user.getPassword()));
        // 添加数据库
        int i = 0;
        try {
            i = adminFeignServiceTemLate.insertUser(user);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        if (i > 0) {
            return Result.success("注册成功");
        }
        return Result.error("服务器繁忙，如重复操作失败请联系管理员，周腾");
    }

    @Override
    public Result getCode(String phone) {
        //数据校验
        if (StringUtils.isEmpty(phone)) {
            return Result.success("手机号不存在");
        }
//        //调用接口
//        User data = adminFeignServiceTemLate.findByPhone(phone);
//
//        log.info("我是大美女"+data);
//        if (null == data) {
//            return Result.error("数据不存在");
//        }
        //获取验证码
        String code = RandomUtil.randomNumbers(4);
        //发短信
        HashMap<String, String> map = new HashMap<>();
        map.put("code", code);
        TelSmsUtils.sendSms(phone, "11111111", map);
        //存redis
        redisTemplate.opsForValue().set(phone, code, 30, TimeUnit.MINUTES);

        return Result.success(code);
    }
}
